package utils

import (
	"flag"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"github.com/spf13/viper"
	"go-malphite/app/common/dto"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"io"
	"log"
	"os"
	"strings"
	"time"
)

var (
	DB      *gorm.DB      // mysql数据库
	Redis   *redis.Client // redis服务器
	Port    int           // 服务端口号
	logFile *os.File      // 日志文件
)

// InitConfig 初始化配置文件
func InitConfig() {
	configFile := flag.String("c", "config/application-prod.yml", "环境配置文件")
	var help bool
	flag.BoolVar(&help, "h", false, "显示帮助信息")
	flag.Parse()
	if help {
		fmt.Fprintf(os.Stderr, "使用方法：\n")
		flag.PrintDefaults()
		os.Exit(0)
	}
	viper.SetConfigFile(*configFile)
	if err := viper.ReadInConfig(); err != nil {
		log.Fatal("配置文件未找到！", err)
	}
	if strings.HasSuffix(*configFile, "prod.yml") {
		gin.SetMode(gin.ReleaseMode)
		gin.DisableConsoleColor()
		InitLog()
	}
}

// InitPort 初始化端口号
func InitPort() {
	Port = viper.GetInt("server.port")
}

// InitLog 自定义初始化日志
func InitLog() {
	fileInfo, err := os.Stat("log")
	if err != nil || !fileInfo.IsDir() {
		err := os.MkdirAll("log", os.ModePerm)
		if err != nil {
			log.Fatal("日志文件创建失败！", err)
		}
	}
	currentTime := time.Now().Format("2006年01月02日15时04分05秒")
	f, err := os.Create(fmt.Sprintf("log/go_malphite_%s.log", currentTime))
	if err != nil {
		log.Fatal("日志文件不存在！", err)
	}
	gin.DefaultWriter = io.MultiWriter(f)
	log.SetOutput(f)
	logFile = f
}

// InitMySQL 初始化mysql
func InitMySQL() {
	host := viper.GetString("mysql.host")
	port := viper.GetInt("mysql.port")
	username := viper.GetString("mysql.username")
	password := viper.GetString("mysql.password")
	source := viper.GetString("mysql.source")
	address := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", username, password, host, port, source)
	// 自定义日志模板，打印SQL语句
	myLog := log.New(os.Stdout, "\r\n", log.LstdFlags)
	if gin.Mode() == gin.DebugMode {
		myLog = log.New(logFile, "\r\n", log.LstdFlags)
	}
	newLogger := logger.New(
		myLog,
		logger.Config{
			SlowThreshold: time.Second, // 慢SQL阈值
			LogLevel:      logger.Info, // 级别
			Colorful:      true,        // 彩色
		},
	)
	db, err := gorm.Open(mysql.Open(address), &gorm.Config{
		Logger: newLogger,
	})
	if err != nil {
		log.Fatal("mysql启动失败，错误原因：", err)
	}
	DB = db
}

// InitRedis 初始化redis
func InitRedis() {
	client := redis.NewClient(&redis.Options{
		Addr:         fmt.Sprintf("%s:%d", viper.GetString("redis.host"), viper.GetInt("redis.port")),
		Password:     viper.GetString("redis.password"),
		DB:           viper.GetInt("redis.DB"),
		PoolSize:     viper.GetInt("redis.poolSize"),
		MinIdleConns: viper.GetInt("redis.minIdleConn"),
	})
	_, err := client.Ping().Result()
	if err != nil {
		log.Fatal("redis启动失败，错误原因：", err)
	}
	Redis = client
}

// InitBanner 初始化banner
func InitBanner() {
	file, err := os.Open("config/banner.txt")
	if err != nil {
		log.Fatal("服务启动失败！原因：", err)
	}
	defer func(file *os.File) {
		err := file.Close()
		if err != nil {
			log.Fatal(err)
		}
	}(file)

	var builder strings.Builder
	buf := make([]byte, 1024)
	for {
		n, err := file.Read(buf)
		if err != nil {
			if err == io.EOF {
				builder.Write(buf[:n])
			}
			break
		}
		builder.Write(buf[:n])
	}
	text := builder.String()

	fmt.Println()
	fmt.Println(text)
	fmt.Println()
}

// InitOther 初始化其它
func InitOther() {
	dto.InitSnowflake("2023-09-04", 1)
}
